package james.gan.remoting.netty;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.SocketAddress;

import org.apache.commons.pool2.impl.GenericObjectPool;

import james.gan.remoting.api.Client;
import james.gan.remoting.api.Remoting;
import james.gan.remoting.api.Server;
import james.gan.remoting.netty.pool.NettyClientPool;
import james.gan.remoting.netty.pool.NettyClientProxy;
import james.gan.remoting.netty.server.NettyServer;

public class NettyRemoting extends Remoting {

	@Override
	public Client getClient() {
		
		return (Client) Proxy.newProxyInstance(Client.class.getClassLoader(), new Class<?>[] { Client.class },
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						if(method.getName().equals("send")){
							
							GenericObjectPool<NettyClientProxy> withSocketAddress = NettyClientPool.getWithSocketAddress((SocketAddress) args[0],
									serialization);
							NettyClientProxy borrowObject = withSocketAddress.borrowObject();
							Method mt = borrowObject.getClass().getMethod("send", new Class<?>[]{method.getParameterTypes()[1]});
							return mt.invoke(borrowObject, args[1]);
						}
						throw new IllegalStateException("Not support method: ["+ method.getName()+"]");
					}
				});
	}

	@Override
	public Server getServer() {
		return new NettyServer(serviceContainer, serialization);
	}

	/*public static void main(String[] args) throws RemotingException {
		NettyRemoting nettyRemoting = new NettyRemoting();
		nettyRemoting.setSerialization(new HessianSerialization());
		Client client = nettyRemoting.getClient();
		InetSocketAddress inetSocketAddress = new InetSocketAddress(7074);
		client.send(inetSocketAddress, new Request());
	}*/
	
	/*public static void main(String[] args) throws Exception {
		NettyRemoting nettyRemoting = new NettyRemoting();
		nettyRemoting.setSerialization(new HessianSerialization());
		Server server = nettyRemoting.getServer();
		server.start(7075, nettyRemoting.getSerialization(), new RegistyServiceContainer());
	}*/
}
